﻿using Heroius.Extension;
using Heroius.Files;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Windows;

namespace Heroius.Cert
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();

            //准备文件夹
            var hpath = $"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).Replace('\\', '/')}/Heroius/HCert/";
            if (!Directory.Exists(hpath))
            {
                Directory.CreateDirectory(hpath);
            }

            //初始化配置
            var settingpath = $"{hpath}setting.config";
            SettingCore = new Dictionary<string, string>();
            if (File.Exists(settingpath))
            {
                EntitySilo silo = new EntitySilo();
                silo.Recursion = true;
                silo.StoreElements = true;
                silo.Load(settingpath);
                silo.Fetch("config", SettingCore);
            }
            this.Closing += (sender, e) => {
                EntitySilo silo = new EntitySilo();
                silo.Recursion = true;
                silo.StoreElements = true;
                silo.Store("config", SettingCore);
                silo.Save(settingpath);
            };
            Setting = new Setting(SettingCore);

            //实例化证书配置
            CertConfig = new CertInfo();
            CertConfig.WorkingDirectory = hpath;

            //准备文件对话框
            diasave = new SaveFileDialog();
            diasave.Filter = "证书配置|*.hco";
            diaload = new OpenFileDialog();
            diaload.Filter = "证书配置|*.hco";

            //构建引擎
            var engineName = $"Heroius.Cert.{Setting.Engine}";
            var asm = Utility.TryLoadAssembly(Utility.GetAbsolutePath($"{engineName}.dll"));
            var t = asm.GetType($"{engineName}.Engine");
            Engine = Activator.CreateInstance(t) as IEngine;
            Engine.Init(SettingCore);
            Engine.SendMessage += Logger_Add;
            EngineSetting = Engine.Setting;

            //界面绑定
            DataContext = this;
        }

        #region 菜单


        SaveFileDialog diasave;
        OpenFileDialog diaload;

        private void SaveConfig_Click(object sender, RoutedEventArgs e)
        {
            diasave.FileName = CertConfig.CertId;//suger
            if (diasave.ShowDialog() == true)
            {
                EntitySilo silo = new EntitySilo();
                silo.Recursion = true;
                silo.StoreElements = true;
                silo.Store("cert", CertConfig);
                silo.Save(diasave.FileName);
            }
        }

        private void LoadConfig_Click(object sender, RoutedEventArgs e)
        {
            if (diaload.ShowDialog() == true)
            {
                try
                {
                    EntitySilo silo = new EntitySilo();
                    silo.Recursion = true;
                    silo.StoreElements = true;
                    silo.Load(diaload.FileName);
                    silo.Fetch("cert", CertConfig);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void About_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show($"HCert OpenSSL Shell v{Assembly.GetExecutingAssembly().GetName().Version.ToString()}\r\n" +
                $"Heroius @ EnvSafe Co.,Ltd. {DateTime.Now.ToString("yyyy")}", "关于");
        }

        #endregion

        #region Logger

        internal void Logger_Add(string obj)
        {
            Dispatcher.Invoke(new Action(() =>
            {
                Logs.Add(obj);
                ScrollLogger.ScrollToBottom();
            }));
        }

        public ObservableCollection<string> Logs { get; private set; } = new ObservableCollection<string>();

        private void Logger_Clear_Click(object sender, RoutedEventArgs e)
        {
            Logs.Clear();
        }

        private void Logger_CopyAll_Click(object sender, RoutedEventArgs e)
        {
            Clipboard.SetText(Logs.Merge("\r\n"));
        }

        private void Logger_CopyItem_Click(object sender, RoutedEventArgs e)
        {
            var log = (sender as FrameworkElement).DataContext as string;
            Clipboard.SetText(log);
        }
        #endregion

        #region 单件

        public CertInfo CertConfig { get; set; }

        public Dictionary<string, string> SettingCore { get; set; }

        public Setting Setting { get; set; }

        public DictEvalEntity EngineSetting { get; set; }

        IEngine Engine;

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        private void ExecuteCertGen(object sender, RoutedEventArgs e)
        {
            var r = Engine.Gen(CertConfig);
            MessageBox.Show(r.Info);
            if (!r.Succeed)
            {
                Logger_Add(r.Info);
            }
        }
    }
}
